package com.pai4j.aigc.service;
import com.pai4j.aigc.llm.AiPlantUmlService;
import com.pai4j.aigc.repository.dao.IPlantUmlDAO;
import com.pai4j.aigc.repository.entity.PlantUmlEntity;
import com.pai4j.common.enums.OutputFormat;
import com.pai4j.common.helper.SessionHelper;
import com.pai4j.common.helper.SseEmitterHelper;
import com.pai4j.common.service.MinioService;
import com.pai4j.common.util.DateUtils;
import com.pai4j.common.util.IDGenerateUtil;
import com.pai4j.domain.dto.aigc.RenderResult;
import com.pai4j.domain.vo.response.UploadResultVO;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.Getter;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.SourceStringReader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

@Service
public class PlantUmlService {
    private static final Log log = LogFactory.getLog(PlantUmlService.class);
    @Resource
    private AiPlantUmlService aiPlantUmlService;
    
    @Resource
    private IPlantUmlDAO plantUmlDAO;

    @Resource
    private MinioService minioService;

    // PlantUML 图片存储路径
    private static final String PLANTUML_IMAGE_PATH = "plantuml/images/";

    
    /**
     * 将PlantUML代码转换为PNG图片
     */
    public byte[] generatePng(String plantUmlCode) throws IOException {
        return renderToBytes(plantUmlCode, FileFormat.PNG);
    }
    
    /**
     * 将PlantUML代码转换为SVG
     */
    public String generateSvg(String plantUmlCode) throws IOException {
        byte[] bytes = renderToBytes(plantUmlCode, FileFormat.SVG);
        return new String(bytes, StandardCharsets.UTF_8);
    }
    
    /**
     * 将PlantUML代码转换为ASCII艺术文本
     */
    public String generateAscii(String plantUmlCode) throws IOException {
        byte[] bytes = renderToBytes(plantUmlCode, FileFormat.ATXT);
        return new String(bytes, StandardCharsets.UTF_8);
    }

    
    /**
     * 新增：根据用户描述直接生成并渲染指定格式，一次完成“生成代码 -> 渲染图片/文本”的闭环
     *
     * @param userPrompt 用户输入
     * @param format 输出格式（PNG/SVG/ASCII）
     * @param optimize 是否先优化代码再渲染
     * @return RenderResult 包含最终PlantUML代码与渲染后的内容字节
     */
    @Transactional(rollbackFor = Exception.class)
    public RenderResult generateAndRenderFromPrompt(String userPrompt, OutputFormat format, boolean optimize) throws Exception {
        // 1. 生成代码
        String code = aiPlantUmlService.generatePlantUmlCode(userPrompt);
        if (optimize) {
            code = aiPlantUmlService.optimizePlantUmlCode(code);
        }

        // 2. 渲染
        FileFormat fileFormat = toFileFormat(format);
        byte[] bytes = renderToBytes(code, fileFormat);
        String contentType = toContentType(format);
        String ext = toExtension(format);
        return  new RenderResult(code, bytes, contentType, ext);
    }


    /**
     * 保存UML图
     */
      public UploadResultVO saveUmlImage(RenderResult renderResult, String userPrompt, String senderId) {
          PlantUmlEntity plantUmlEntity = new PlantUmlEntity();
          plantUmlEntity.setUserPrompt(userPrompt);
          plantUmlEntity.setPlantUmlCode(renderResult.getPlantUmlCode());
          plantUmlEntity.setStatus("SUCCESS");
          plantUmlEntity.setCreateBy(senderId);
          // 2) 上传到MinIO，返回URL
          UploadResultVO uploadResult = uploadBytesToMinio(renderResult.getContentBytes(), "svg", "image/svg+xml");
          if (uploadResult == null) {
              return null;
          }
          plantUmlEntity.setImage(uploadResult.getUrl());
          plantUmlEntity.setDiagramType(String.valueOf(OutputFormat.SVG));
          plantUmlDAO.save(plantUmlEntity);
          return uploadResult;
    }



    
    /**
     * 统一渲染入口：将PlantUML代码渲染为指定格式字节数组
     */
    private byte[] renderToBytes(String plantUmlCode, FileFormat fileFormat) throws IOException {
        SourceStringReader reader = new SourceStringReader(plantUmlCode);
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            reader.outputImage(outputStream, new FileFormatOption(fileFormat));
            return outputStream.toByteArray();
        }
    }
    
    private FileFormat toFileFormat(OutputFormat format) {
        return switch (format) {
            case PNG -> FileFormat.PNG;
            case SVG -> FileFormat.SVG;
            case ASCII -> FileFormat.ATXT;
        };
    }
    
    private String toContentType(OutputFormat format) {
        return switch (format) {
            case PNG -> "image/png";
            case SVG -> "image/svg+xml";
            case ASCII -> "text/plain; charset=UTF-8";
        };
    }
    
    private String toExtension(OutputFormat format) {
        return switch (format) {
            case PNG -> "png";
            case SVG -> "svg";
            case ASCII -> "txt";
        };
    }



    /**
     * 将字节数组上传到MinIO
     */
    private UploadResultVO uploadBytesToMinio(byte[] data, String extension, String contentType) {
        try {
            String dateStr = DateUtils.getDate2String(DateUtils.YYYYMMDD, new Date());
            String uuid = IDGenerateUtil.uuid().substring(0, 8);
            String fileName = dateStr + "_" + uuid + "." + extension;

            String fullPath = PLANTUML_IMAGE_PATH + dateStr + "/";
            MultipartFile file = new MockMultipartFile(fileName, fileName, contentType, data);
            return minioService.upload(fullPath, file, true);
        } catch (Exception e) {
            log.error("上传UML图片到MinIO失败", e);
            return null;
        }
    }
}
